package cn.geminis.lowcode.compiler.code;

import cn.geminis.lowcode.compiler.util.JdkTreeMakerUtils;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.MethodInvocationTree;

import java.util.Arrays;
import java.util.List;

/**
 * @author puddi
 */
public class LcApply extends AbstractExpression<MethodInvocationTree> {

    private final List<InvokeInfo> invokes;

    public LcApply(String expression, AbstractExpression<?>... args) {
        this.invokes = List.of(new InvokeInfo(expression, args));
    }

    public LcApply(List<InvokeInfo> invokes) {
        this.invokes = invokes;
    }

    @Override
    protected MethodInvocationTree createJdkTree() {
        var firstInvoke = invokes.get(0);
        var invocation = JdkTreeMakerUtils.apply(
                new LcIdent(firstInvoke.expression).getJdkTree(),
                Arrays.stream(firstInvoke.args).map(AbstractExpression::getJdkTree).toArray(ExpressionTree[]::new)
        );
        for (var i = 1; i < invokes.size(); i++) {
            var invoke = invokes.get(i);
            invocation = JdkTreeMakerUtils.apply(
                    JdkTreeMakerUtils.select(invocation, invoke.expression),
                    Arrays.stream(invoke.args).map(AbstractExpression::getJdkTree).toArray(ExpressionTree[]::new)
            );
        }
        return invocation;
    }

    public record InvokeInfo(String expression, AbstractExpression<?>... args) {
    }

}
